<?php
require_once __DIR__ . '/../../vendor/autoload.php';
use Workerman\Worker;

// 创建一个基于 WebSocket 协议的 Worker 实例，监听 2346 端口
$ws_worker = new Worker("websocket://0.0.0.0:2346");

// 设置进程数量，可根据服务器性能调整
$ws_worker->count = 4;

// 存储所有客户端连接及相关信息
$clients = [];
// 存储分组信息，键为分组名，值为连接 ID 数组
$groups = [];

// 当有新的客户端连接时触发
$ws_worker->onConnect = function ($connection) use (&$clients, &$groups) {
    // 假设这里的 userId 是通过某种身份验证机制获取的，暂时设为一个示例值
    $userId = uniqid();
    $clients[$connection->id] = [
        'connection' => $connection,
        'userId' => $userId,
        'group' => null // 初始时不分组
    ];
};

// 封装单条发送功能
function sendToSingleClient($clientId, $message, &$clients) {
    if (isset($clients[$clientId])) {
        $clients[$clientId]['connection']->send($message);
        return true;
    }
    return false;
}

// 封装分组发送功能
function sendToGroup($groupName, $message, &$clients, &$groups) {
    if (isset($groups[$groupName])) {
        foreach ($groups[$groupName] as $clientId) {
            if (isset($clients[$clientId])) {
                $clients[$clientId]['connection']->send($message);
            }
        }
        return true;
    }
    return false;
}

// 封装广播功能
function broadcast($message, &$clients) {
    foreach ($clients as $client) {
        $client['connection']->send($message);
    }
}

// 当收到客户端消息时触发
$ws_worker->onMessage = function ($connection, $data) use (&$clients, &$groups) {
    $senderId = $clients[$connection->id]['userId'];
    $data = json_decode($data, true);

    if ($data && isset($data['type'])) {
        switch ($data['type']) {
            case 'single':
                if (isset($data['targetId'])) {
                    sendToSingleClient($data['targetId'], $data['message'], $clients);
                }
                break;
            case 'group':
                if (isset($data['groupName'])) {
                    sendToGroup($data['groupName'], $data['message'], $clients, $groups);
                }
                break;
            case 'broadcast':
                broadcast($data['message'], $clients);
                break;
            case 'joinGroup':
                if (isset($data['groupName'])) {
                    $groupName = $data['groupName'];
                    if (!isset($groups[$groupName])) {
                        $groups[$groupName] = [];
                    }
                    if (!in_array($connection->id, $groups[$groupName])) {
                        $groups[$groupName][] = $connection->id;
                        $clients[$connection->id]['group'] = $groupName;
                    }
                    $connection->send("你已加入分组 $groupName");
                }
                break;
        }
    } else {
        // 普通消息广播
        $message = "用户 $senderId 说: $data";
        broadcast($message, $clients);
    }
};

// 当客户端断开连接时触发
$ws_worker->onClose = function ($connection) use (&$clients, &$groups) {
    $clientGroup = $clients[$connection->id]['group'];
    if ($clientGroup && isset($groups[$clientGroup])) {
        $key = array_search($connection->id, $groups[$clientGroup]);
        if ($key!== false) {
            unset($groups[$clientGroup][$key]);
        }
    }
    // 从客户端列表中移除断开的连接
    unset($clients[$connection->id]);
};

// 启动 Workerman 服务
Worker::runAll();